package dnl.dtools.grm.remote;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;

import ajul.io.FileUtils;
import ajul.lang.Args;

import com.google.inject.Singleton;

import dnl.logging.LightLog;

/**
 * Manages session infos.
 *  
 * @author Daniel Ore
 */
@Singleton
public class RemoteSessionsManager {

	private static final String SSH_SESSIONS_XML_FILE = "ssh.sessions.xml";
	private Map<String, UserPasswordRemoteSessionInfo> registeredSessions = new HashMap<String, UserPasswordRemoteSessionInfo>();
	private Map<HostAndUserPair, UserPasswordRemoteSessionInfo> registeredSessionsByHostAndUser = new HashMap<HostAndUserPair, UserPasswordRemoteSessionInfo>();
		
	public RemoteSessionsManager() {
		loadPersistedSessions();
	}

    public Collection<String> getAllRegisteredSessionNames(){
        return registeredSessions.keySet(); 
    }

    public Collection<UserPasswordRemoteSessionInfo> getAllRegisteredSessions(){
        return registeredSessions.values();
    }

    public void registerSession(UserPasswordRemoteSessionInfo newSession){
		Args.assertNotNull(newSession);
		Args.assertNotNull(newSession.getSessionName());
		Args.assertNotNull(newSession.getHost());
		Args.assertNotNull(newSession.getUserName());
		if(registeredSessions.get(newSession.getSessionName()) != null){
			throw new IllegalArgumentException("A session with that name already exists.");
		}
		registeredSessions.put(newSession.getSessionName(), newSession);
		//newSession.setPasswordManager(passwordManager);
		registeredSessionsByHostAndUser.put(new HostAndUserPair(newSession.getHost(), newSession
				.getUserName()), newSession);
	}
	
	public void removeSession(UserPasswordRemoteSessionInfo session){
		Args.assertNotNull(session);
		registeredSessions.remove(session.getSessionName());
	}

	public UserPasswordRemoteSessionInfo getRegisteredSession(String sessionName){
		UserPasswordRemoteSessionInfo sess = registeredSessions.get(sessionName);
		return sess;
	}

	public UserPasswordRemoteSessionInfo getRegisteredSession(String hostName, String userName){
		return registeredSessionsByHostAndUser.get(new HostAndUserPair(hostName, userName));
	}
	
	private void loadPersistedSessions(){
		File xmlFile = new File(SSH_SESSIONS_XML_FILE);
		if(!xmlFile.exists()){
			LightLog.warn("Sessions file not found ("+SSH_SESSIONS_XML_FILE+").");
			return;
		}
		
		Digester digester = new Digester();
		
		digester.addObjectCreate("*/session", UserPasswordRemoteSessionInfo.class);
		digester.addBeanPropertySetter("*/session/name", "sessionName");
		digester.addBeanPropertySetter("*/session/host", "host");
		digester.addBeanPropertySetter("*/session/user", "userName");
		digester.addBeanPropertySetter("*/session/password", "password");
		digester.addBeanPropertySetter("*/session/remoteDir", "remoteDir");
	    
		digester.push(this);
		digester.addSetNext( "*/session", "registerSession" );
	    try {
	      digester.parse(SSH_SESSIONS_XML_FILE);
	    }
	    catch (IOException ex) {
	    	LightLog.error("Cannot read config file.");
	    }
	    catch (SAXException ex) {
	    	ex.printStackTrace();
	    	LightLog.error("Configuration cannot be parsed.");
	    }
	}	
	
	public void saveSessions(){
		StringBuffer sb = new StringBuffer();
		sb.append("<sessions>\n");
		for (UserPasswordRemoteSessionInfo sshSess : registeredSessions.values()) {
			sb.append(sshSess.toXml());
		}
		sb.append("</sessions>");
		try {
			FileUtils.writeFile(new File(SSH_SESSIONS_XML_FILE), sb.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
